//函数扩展
//rest参数 ...arg 数组
//arguments 参数集合 类似数组
function f(...arg){
    //console.log(arg)  //[10,20,30]
    let filterNum = arg.filter(v=>v>20);
    console.log(filterNum);  //[30]
};
f(10,20,30)

//其它用法
function f1(a,b,...c){
    console.log(c)
};
f1(10,20,30,40,50)

//arg参数之后不能再有其它参数
// function f1(a,...b,c){
//     console.log(b);  //error
// };
// f1(10,20,30,40,50);

//题目：1 2 3 4 5 + 6
function f2(a,...b){
    let sum = b.reduce((total,cur)=>total+cur,a);
    console.log(sum);
};
f2(6,1,2,3,4,5)

//箭头函数
var f = v => v;
//f变量名 = v参数 => v函数体
var f = function(){
    return 'f'
};
var f = () => 'f';

var f = function(n1,n2){
    return n1+n2
};
var f = (n1,n2)=>n1+n2;

var f = function(n1,n2){
    return {n1,n2}
};
var f = (n1,n2)=>({n1,n2});  //返回对象，需要添加()
f('jack',1)

//定义默认值
var f = (x, y = 1) => x + y;
f(10);

let f = ({ x = 0, y = 0 } = {}) => [x, y];
f({ x: 3, y: 3})

let f = function({x=0,y=0}={}){  //{x=0,y=0} = { x: 3, y: 3} || {};
    return [x,y]
};
f({x:3,y:3});

//箭头函数，简化了函数的定义
//箭头函数的坑
//1、箭头函数不能当作构造函数，不可以使用new 命令
let Fn = (name)=>{
    this.name = name;
};
var fn = new Fn('jack');  //Fn is not a constructor

//2、箭头函数没有原型对象
function fun(){}
fun.prototype;

var fun2=()=>{}
fun2.prototype;

//3、不可以使用arguments对象   ...rest
let fn3 = ()=>{
    console.log(arguments[2])  //arguments is not defined
};
fn3(1,2,3,4,5,6)

//4、this指向
// let x = 'x';
// let obj = {
//     x:'x2',
//     getX:function(){
//         console.log(this.x)  //this谁调用指向的是谁
//     }
// };
// obj.getX();

let x = 'x';
let obj = {
    x:'x2',
    getX:()=>{
        console.log(this.x)
    }
};
obj.getX();
//箭头函数中this指向规则：箭头函数不绑定this，它会捕获其所在（定义的位置）上下文的this的值，作为自己的this

//call() apply() bind()
// var id = 1;
// function fn(){
//     return this.id
// };
// var o1 = {
//     id:100
// };
// //fn()函数中this的指向o1(相当于fn在o1对象中执行)
// fn.apply(o1);

var id = 1;
let fn5 = () => this.id;
var o1 = {
    id:100
};
fn5.apply(o1);  //1
